#include <stdio.h>
#include <stdlib.h>

// 1. 初始化数据库，此时的数据库是文件
// 2. 读数据库，生成内存数据模型。链表
// 3. 增 查 改 删 排序
// 4. 更新数据库
typedef struct student
{
    char name[30];
    char sex;
    int age;
    float score;
}Stu;

typedef struct _StuNode
{
    Stu data;
    struct _StuNode *next;

}StuNode;

void initDate2File()
{
    Stu s[4] =
    {
        "ldh",'x',50,100,
        "zxy",'x',60,98,
        "lm",'f',50,88,
        "gfc",'m',49,90
    };
    FILE * pf = fopen("stu.data","w+");
    if( NULL == pf)
    {
        exit(-1);
    }

    fwrite((void*)s,sizeof (s),1,pf);
    fclose(pf);
    return ;
}

StuNode *createListFromFile(char *filepath)
{
    FILE * pf = fopen(filepath,"r+");
    if(NULL == pf)
    {
        exit(-1);
    }

    StuNode *head = (StuNode *)malloc(sizeof(StuNode));
    head -> next = NULL;

    StuNode *cur = (StuNode *)malloc(sizeof(StuNode));  // 1 0
    while (fread((void*)&cur -> data,sizeof(Stu),1,pf)) {
        cur -> next = head -> next;
        head -> next = cur;
        cur = (StuNode *)malloc(sizeof(StuNode));
    }
    free(cur);

    return head;
}

void traverseStuList(StuNode * head)
{
    printf("\t\t Student Management System \n\n");
    printf("\t\t\tCopyLeft: GPLv3\n\n");
    printf("\tname\tsex\tage\tscore\n");
    head = head -> next;
    while (head) {
        printf("\t%s\t\t%c\t%d\t%.2f\n",head->data.name,head->data.sex,head->data.age,head->data.score);
        head = head->next;
    }
    putchar(10);
}

void addListStuNode(StuNode *head)
{
    StuNode *cur = (StuNode *)malloc(sizeof (StuNode));
    printf("name :");
    scanf("%s",cur -> data.name);

    getchar();
    printf("sex :");
    scanf("%c",&cur -> data.sex);

    printf("age :");
    scanf("%d",&cur -> data.age);

    printf("score :");
    scanf("%f",&cur -> data.score);

    cur->next = head -> next;
    head->next= cur;

}

StuNode * searchListStu(StuNode *head)
{
    char name[30];
    printf("Please input your search name: ");
    scanf("%s",name);

    head = head->next;
    while (head) {
        if(strcmp(head->data.name,name) == 0)
        {
            break;
        }
        head = head -> next;
    }
    return head;
}


void deleteListNodeStu(StuNode *head)
{
    StuNode *pfind = searchListStu(head);
    if(pfind == NULL)
    {
        printf("数据不存在！\n");
        getchar();
        return ;
    }
    while (head->next != pfind) {
        head = head->next;
    }
    head->next =pfind->next;
    free(pfind);
    return ;
}


int lenListStu(StuNode * head)
{
    int len = 0;
    head = head->next;
    while (head) {
        len++;
        head = head->next;
    }
    return len;
}
void sortListStu(StuNode *head)
{
    int len = lenListStu(head);
    StuNode *prep,*p,*q;
    for(int i =0; i< len -1;i++)
    {
        prep = head;
        p = prep->next;
        q = p->next;
        for(int j=0; j< len-1-i; j++)
        {
            if(strcmp(p->data.name,q->data.name) > 0)
            {
                prep->next = q;
                p->next = q->next;
                q->next = p;

                prep = q;
                q = p->next;
                continue;
            }
            prep = prep ->next;
            p = q -> next;
            q = p -> next;
        }
    }
}

void saveListStu2File(StuNode * head,char *filepath)
{
    FILE *pf = fopen(filepath,"w+");
    if(NULL == pf)
    {
        exit(-1);
    }
    head = head -> next;
    while (head) {
        fwrite((void*)&head->data,sizeof (Stu),1,pf);
        head = head -> next;
    }
    fclose(pf);
}

void destoryListStu(StuNode * head)
{
    StuNode *t;
    while (head) {
        t = head;
        head = head -> next;
        free(t);
    }
}

int main()
{
//    initDate2File();
    StuNode *head = createListFromFile("stu.data");

    while (1) {
        system("cls");
        traverseStuList(head);
        printf("1 -> add \t 2 -> search \t 3 -> delete \t 4 -> sort\t 5 -> exit \n");
        int choice;
        StuNode *pfind;
        scanf("%d",&choice);
        switch (choice) {
        case 1:
            addListStuNode(head);
            break;
        case 2:
            if( pfind = searchListStu(head))
            {
                printf("数据已找到\n");
                printf("\t%s\t\t%c\t%d\t%.2f\n",pfind->data.name,pfind->data.sex,pfind->data.age,pfind->data.score);
            }
            else{
                printf("未找到数据\n");
            }
            getchar();
            break;
        case 3:
            deleteListNodeStu(head);
            break;
        case 4:
            sortListStu(head);
            break;
        case 5:
            saveListStu2File(head,"stu.data");
            destoryListStu(head);
            return 0;
        default:
            printf("输入有误！请检测输入内容！\n");
        }
    }
    return 0;
}
